#pragma once
#include <common.hpp>
#include "Vector.hpp"
#undef min
#undef max

namespace zzz{
template <typename T>
class Vector<4, T> : public VectorBase<4, T>
{
protected:
  using VectorBase<4, T>::v;
public:
  //constructor
  Vector(void){}
  Vector(const Vector<4, T>& a):VectorBase<4, T>(a){}
  Vector(const T &a1,const T &b,const T &c,const T &d){v[0]=a1; v[1]=b; v[2]=c; v[3]=d;}
  Vector(const VectorBase<4, T>& a):VectorBase<4, T>(a){}
  explicit Vector(const T &a1):VectorBase<4, T>(a1){}
  explicit Vector(const VectorBase<3, T> &a, const T &b):VectorBase<4, T>(a, b){}
  explicit Vector(const VectorBase<5, T> &a):VectorBase<4, T>(a){}
  template<typename T1> explicit Vector(const T1 *p):VectorBase<4, T>(p) {}
  template<typename T1> explicit Vector(const Vector<4,T1>& a1):VectorBase<4, T>(a1) {}
  template<typename T1> explicit Vector(const VectorBase<4,T1>& a1):VectorBase<4, T>(a1) {}

  //assign
  inline const Vector<4, T> &operator=(const Vector<4, T>& a){VectorBase<4, T>::operator =(a); return *this;}
  inline void Set(const T &a, const T &b, const T &c, const T &d){v[0]=a; v[1]=b; v[2]=c; v[3]=d;}
  using VectorBase<4, T>::operator=;

  // alias
  inline T& x(){return v[0];}
  inline T& y(){return v[1];}
  inline T& z(){return v[2];}
  inline T& w(){return v[3];}
  inline T& r(){return v[0];}
  inline T& g(){return v[1];}
  inline T& b(){return v[2];}
  inline T& a(){return v[3];}
  inline const T& x()const {return v[0];}
  inline const T& y()const {return v[1];}
  inline const T& z()const {return v[2];}
  inline const T& w()const {return v[3];}
  inline const T& r()const {return v[0];}
  inline const T& g()const {return v[1];}
  inline const T& b()const {return v[2];}
  inline const T& a()const {return v[3];}

};

typedef Vector<4,zint8> Vector4i8;
typedef Vector<4,zuint8> Vector4ui8;
typedef Vector<4,zint8> Vector4i16;
typedef Vector<4,zuint8> Vector4ui16;
typedef Vector<4,zint8> Vector4i32;
typedef Vector<4,zuint8> Vector4ui32;
typedef Vector<4,zint8> Vector4i64;
typedef Vector<4,zuint8> Vector4ui64;
typedef Vector<4,zfloat32> Vector4f32;
typedef Vector<4,zfloat64> Vector4f64;


typedef Vector<4,zuchar> Vector4uc;
typedef Vector<4,zuint> Vector4ui;
typedef Vector<4,int> Vector4i;
typedef Vector<4,float> Vector4f;
typedef Vector<4,double> Vector4d;

}
